<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>video录制</title>
  <style>
    #container {
      display: flex;
      flex-wrap: wrap;
      justify-content: center;
      align-items: center;
    }

    .controls {
      padding: 0 10px;
    }
  </style>
</head>

<body>
  <div class="layui-body">
    <div id="container">
      <video id="gum" autoplay muted></video>
      <div class="controls">
        <button id="record" disabled>开始录制</button>
        <button id="play" disabled>播放</button>
        <button id="download" disabled>下载</button>
        <span id="tEl"></span>
      </div>
      <video id="gum2" controls="controls" autoplay style="display:none"></video>
    </div>
  </div>
</body>
<script>
  class RecordingVideo {
    // 播放时长
    duration = 0
    // 录制流媒体
    mediaRecorder
    // 录制的数据
    recordedBlobs
    // 倒计时interlval
    intervalId
    // 摄像头流媒体
    stream
    // 录制时长
    maxD = 150
    // 倒计时初始值
    count = 150
    // 页面dom
    gumVideo = document.querySelector('#gum')
    gumVideo2 = document.querySelector('#gum2')
    recordButton = document.querySelector('#record')
    playButton = document.querySelector('#play')
    downloadButton = document.querySelector('#download')
    tEL = document.getElementById('tEl')
    constructor() {
      const constraints = {
        audio: true,
        video: {
          facingMode: "user",
          width: 400,//视频宽度
          height: 400,//视频高度
          frameRate: 60,//每秒60帧
        }
      }
      const isSecureOrigin = location.protocol === 'https:' || location.hostname === 'localhost'

      console.log(isSecureOrigin)
      if (!isSecureOrigin) {
        alert('getUserMedia() 必须在https或localhost下使用')
        location.protocol = 'HTTPS'
      }
      this.recordButton.onclick = () => this.toggleRecording()
      this.playButton.onclick = () => this.play()
      this.downloadButton.onclick = () => this.download()
      this.gumVideo2.width = constraints.video.width
      this.gumVideo2.height = constraints.video.height
      // 获取摄像头流媒体
      this.getUserMedia(constraints, (stream) => {
        // 摄像头流媒体成功回调
        this.recordButton.disabled = false
        this.stream = stream
        this.gumVideo.srcObject = stream
      }, (e) => {
        // 摄像头流媒体失败回调
        if (error.message === 'Permission denied') {
          alert('您已经禁止使用摄像头，请到设置-通用-微信存储空间-管理微信存储空间-点击‘清理其他微信账号聊天数据’')
        }
        console.log('navigator.getUserMedia error: ', error)
      })

    }
    // 获取摄像头流媒体
    getUserMedia(constraints, success, error) {
      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        //最新的标准API
        navigator.mediaDevices.getUserMedia(constraints).then(success).catch(error)
      } else if (navigator.webkitGetUserMedia) {
        //webkit核心浏览器
        navigator.webkitGetUserMedia(constraints, success, error)
      } else if (navigator.mozGetUserMedia) {
        //firfox浏览器
        navigator.mozGetUserMedia(constraints, success, error)
      } else if (navigator.getUserMedia) {
        //旧版API
        navigator.getUserMedia(constraints, success, error)
      }
    }
    // 开始录制的事件
    toggleRecording() {
      const tEl = this.tEL
      if (this.recordButton.textContent === '开始录制') {
        tEl.innerHTML = ''
        this.startRecording()
        clearInterval(this.intervalId)
        tEl.innerHTML = '剩余时间：' + this.count + '秒'
        this.count--
        this.intervalId = setInterval(() => {
          tEl.innerHTML = '剩余时间：' + this.count + '秒'
          if (this.count <= 0) {
            clearInterval(this.intervalId)
            this.duration = this.maxD - this.count
            this.count = this.maxD
            this.stopRecording()
            this.recordButton.textContent = '开始录制'
            this.downloadButton.disabled = false
            this.playButton.disabled = false
          } else {
            this.count--
          }

        }, 1000)
      } else {
        clearInterval(this.intervalId)

        this.duration = this.maxD - this.count
        this.count = this.maxD
        this.stopRecording()
        this.recordButton.textContent = '开始录制'
        this.playButton.disabled = false
        this.downloadButton.disabled = false
      }
    }
    // 开始录制
    startRecording() {
      const isSafari = !(!(/Safari/.test(navigator.userAgent) && !/Chrome/.test(navigator.userAgent)))

      this.recordedBlobs = []
      const options = {
        audioBitsPerSecond: 128000,
        videoBitsPerSecond: 2500000,
        mimeType: isSafari ? 'video/mp4' : 'video/webm'
      }
      try {
        this.mediaRecorder = new MediaRecorder(this.stream, options)
      } catch (e) {
        alert('MediaRecorder创建失败: ' + e + '. mimeType: ' + options.mimeType)
        return
      }
      this.recordButton.textContent = '结束录制'
      this.downloadButton.disabled = true
      this.playButton.disabled = true

      // 录制中
      this.mediaRecorder.ondataavailable = event => {
        if (event.data && event.data.size > 0) {
          this.recordedBlobs.push(event.data)
        }
      }
      // 录制结束回调
      this.mediaRecorder.onstop = event => {
        console.log('Recorder stopped: ', event)
      }
      // 开始录制
      this.mediaRecorder.start(10);
    }
    // 停止录制
    stopRecording() {
      tEl.innerHTML = '录制完成'
      this.mediaRecorder.stop()
    }
    // 下载视频
    download() {
      const blob = new Blob(this.recordedBlobs, { type: 'video/mp4' })
      const a = document.createElement('a')
      a.setAttribute('download', Date.now() + '.mp4')
      a.href = URL.createObjectURL(blob)
      a.click()
    }
    // 点击播放
    play() {
      const { recordedBlobs, gumVideo2 } = this
      const blob = new Blob(recordedBlobs, { type: 'video/mp4' })
      const size = parseInt(blob.size / 1024)
      let strSize = ''
      if (size < 1024) {
        strSize = size + 'KB'
      } else {
        strSize = (size / 1024).toFixed(2) + 'MB'
      }
      alert('播放时长：' + this.duration + '秒, 大小：' + strSize)
      const videoURL = URL.createObjectURL(blob)
      gumVideo2.style.display = ''
      gumVideo2.src = videoURL

    }

  }
  new RecordingVideo()

</script>

</html>